home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''Provides a SpeechServer factory for gnome-speech drivers.'''
- __id__ = '$Id: gnomespeechfactory.py 4567 2009-02-16 22:13:55Z wwalker $'
- __version__ = '$Revision: 4567 $'
- __date__ = '$Date: 2009-02-16 17:13:55 -0500 (Mon, 16 Feb 2009) $'
- __copyright__ = 'Copyright (c) 2005-2008 Sun Microsystems Inc.'
- __license__ = 'LGPL'
- import logging
- log = logging.getLogger('speech')
- import gobject
- import Queue
- import threading
- import time
- import bonobo
- import ORBit
- import chnames
- import debug
- import orca
- import orca_state
- import punctuation_settings
- import settings
- import speech
- import speechserver
- from acss import ACSS
- from orca_i18n import _
- ORBit.load_typelib('GNOME_Speech')
- import GNOME.Speech as GNOME
- import GNOME__POA.Speech as GNOME__POA
-
- def _matchLanguage(desired, actual):
- """Compares a desired language to an actual language and returns
- a numerical value representing the degree of match. The expected
- language format is a string similar to the following, where the
- delimiter can be '-' '_' or '.':
-
- de-DE (German for Germany)
- en-US (English as used in the United States)
-
- Additional extensions for variants or dialects are allowed as well.
-
- The return value is one of the following:
-
- 0 - no match at all
- 1 - some match
- 2 - exact match
- """
- if desired == actual:
- return 2
- if not desired or not actual:
- return 0
- desired = desired.lower().replace('-', '_').replace('.', '_').split('_')
- actual = actual.lower().replace('-', '_').replace('.', '_').split('_')
- matchCount = 0
- for i in range(0, min(len(desired), len(actual))):
- if desired[i] == actual[i]:
- matchCount += 1
- continue
- not actual
-
- if matchCount == len(desired):
- return 2
- if matchCount:
- return 1
- return 0
-
-
- class _SayAll:
-
- def __init__(self, iterator, context, utteranceId, progressCallback):
- self.utteranceIterator = iterator
- self.currentContext = context
- self.idForCurrentContext = utteranceId
- self.progressCallback = progressCallback
-
-
-
- class _Speaker(GNOME__POA.Speech.SpeechCallback):
- """Implements gnome-speech's SpeechCallback class. The gnome-speech
- server only allows one speech callback to be registered with a speaker
- and there's no way to unregister it. So...we need to handle stuff
- like that on our own. This class handles this for us and also delegates
- all calls to the 'real' gnome speech speaker.
- """
-
- def __init__(self, gnome_speaker, voice):
- self.gnome_speaker = gnome_speaker
- if settings.enableSpeechCallbacks:
- gnome_speaker.registerSpeechCallback(self._this())
-
- self._Speaker__callbacks = []
- self.voiceInfo = [
- voice.name,
- voice.language,
- voice.gender]
-
-
- def registerCallback(self, callback):
- self._Speaker__callbacks.append(callback)
-
-
- def deregisterCallback(self, callback):
- self._Speaker__callbacks.remove(callback)
-
-
- def notify(self, progressType, utteranceId, offset):
- '''Called by GNOME Speech when the GNOME Speech driver generates
- a callback.
-
- Arguments:
- - progressType: one of GNOME.Speech.speech_callback_speech_started,
- GNOME.Speech.speech_callback_speech_progress,
- GNOME.Speech.speech_callback_speech_ended
- - utteranceId: the id of the utterance (returned by say)
- - offset: the character offset into the utterance (for progress)
- '''
- for callback in self._Speaker__callbacks:
- callback.notify(progressType, utteranceId, offset)
-
-
-
- def say(self, text):
- if isinstance(text, unicode):
- text = text.encode('UTF-8')
-
- return self.gnome_speaker.say(text)
-
-
- def stop(self):
- self.gnome_speaker.stop()
-
-
- def getSupportedParameters(self):
- return self.gnome_speaker.getSupportedParameters()
-
-
- def getParameterValue(self, name):
- return self.gnome_speaker.getParameterValue(name)
-
-
- def setParameterValue(self, name, value):
- return self.gnome_speaker.setParameterValue(name, value)
-
-
- def unref(self):
-
- try:
- self.gnome_speaker.unref()
- except:
- pass
-
-
-
-
- class SpeechServer(speechserver.SpeechServer):
- '''Provides SpeechServer implementation for gnome-speech.'''
- __activeServers = { }
-
- def __activateDriver(iid):
- driver = bonobo.activation.activate_from_id(iid, 0, False)
- driver = driver._narrow(GNOME.Speech.SynthesisDriver)
- isInitialized = driver.isInitialized()
- if not isInitialized:
- isInitialized = driver.driverInit()
-
- if not isInitialized:
-
- try:
- driver.unref()
- except:
- pass
-
- driver = None
-
- return driver
-
- __activateDriver = staticmethod(__activateDriver)
-
- def __createServer(iid):
- server = None
- if iid in SpeechServer._SpeechServer__activeServers:
- server = SpeechServer._SpeechServer__activeServers[iid]
- else:
- driver = SpeechServer._SpeechServer__activateDriver(iid)
- if driver:
- server = SpeechServer(driver, iid)
- SpeechServer._SpeechServer__activeServers[iid] = server
-
- return server
-
- __createServer = staticmethod(__createServer)
-
- def getFactoryName():
- '''Returns a localized name describing this factory.'''
- return _('GNOME Speech Services')
-
- getFactoryName = staticmethod(getFactoryName)
-
- def getSpeechServers():
- '''Gets available speech servers as a list. The caller
- is responsible for calling the shutdown() method of each
- speech server returned.
- '''
- knownServers = bonobo.activation.query("repo_ids.has('IDL:GNOME/Speech/SynthesisDriver:0.3')")
- for server in knownServers:
- if server.iid not in SpeechServer._SpeechServer__activeServers:
-
- try:
- SpeechServer._SpeechServer__createServer(server.iid)
- debug.printException(debug.LEVEL_WARNING)
-
- continue
-
- return SpeechServer._SpeechServer__activeServers.values()
-
- getSpeechServers = staticmethod(getSpeechServers)
-
- def getSpeechServer(info = None):
- '''Gets a given SpeechServer based upon the info.
- See SpeechServer.getInfo() for more info.
- '''
- if info and info[1] in SpeechServer._SpeechServer__activeServers:
- return SpeechServer._SpeechServer__activeServers[info[1]]
- server = None
- gservers = bonobo.activation.query("repo_ids.has('IDL:GNOME/Speech/SynthesisDriver:0.3')")
- if len(gservers) == 0:
- return None
- gserver = None
- if not info:
- gserver = gservers[0]
- else:
- for s in gservers:
- if s.iid == info[1]:
- gserver = s
- break
- continue
- info[1] in SpeechServer._SpeechServer__activeServers
-
- if not gserver:
- return None
- server = None
-
- try:
- server = SpeechServer._SpeechServer__createServer(gserver.iid)
- except:
- gserver
- debug.printException(debug.LEVEL_WARNING)
-
- if not server:
- for s in gservers:
-
- try:
- server = SpeechServer._SpeechServer__createServer(s.iid)
- if server:
- break
- continue
- debug.printException(debug.LEVEL_WARNING)
- continue
-
-
-
- return server
-
- getSpeechServer = staticmethod(getSpeechServer)
-
- def shutdownActiveServers():
- '''Cleans up and shuts down this factory.
- '''
- for key in SpeechServer._SpeechServer__activeServers.keys():
- server = SpeechServer._SpeechServer__activeServers[key]
- server.shutdown()
-
-
- shutdownActiveServers = staticmethod(shutdownActiveServers)
-
- def __init__(self, driver, iid):
- speechserver.SpeechServer.__init__(self)
- self._SpeechServer__speakers = { }
- self._SpeechServer__pitchInfo = { }
- self._SpeechServer__rateInfo = { }
- self._SpeechServer__volumeInfo = { }
- self._SpeechServer__driver = driver
- self._SpeechServer__driverName = driver.driverName
- self._SpeechServer__iid = iid
- self._SpeechServer__sayAll = None
- self._SpeechServer__isSpeaking = False
- self._SpeechServer__eventQueue = Queue.Queue(0)
- self._SpeechServer__gidleId = 0
- self._SpeechServer__gidleLock = threading.Lock()
- self._SpeechServer__lastResetTime = 0
- self._SpeechServer__lastText = None
- self.textCharIndices = []
-
-
- def __getRate(self, speaker):
- '''Gets the voice-independent ACSS rate value of a voice.'''
- if speaker not in self._SpeechServer__rateInfo:
- return 50
- (minRate, averageRate, maxRate) = self._SpeechServer__rateInfo[speaker]
- rate = speaker.getParameterValue('rate')
- if rate < averageRate:
- return 50 * (rate - minRate) / (averageRate - minRate)
- if rate > averageRate:
- return 50 + 50 * (rate - averageRate) / (maxRate - averageRate)
- return 50
-
-
- def __setRate(self, speaker, acssRate):
- '''Determines the voice-specific rate setting for the
- voice-independent ACSS rate value.
- '''
- if speaker not in self._SpeechServer__rateInfo:
- return None
- (minRate, averageRate, maxRate) = self._SpeechServer__rateInfo[speaker]
- if acssRate < 50:
- rate = minRate + acssRate * (averageRate - minRate) / 50
- elif acssRate > 50:
- rate = averageRate + (acssRate - 50) * (maxRate - averageRate) / 50
- else:
- rate = averageRate
- speaker.setParameterValue('rate', rate)
-
-
- def __getPitch(self, speaker):
- '''Gets the voice-specific pitch setting for the
- voice-independent ACSS pitch value.
-
- Returns the voice-specific pitch setting.
- '''
- if speaker not in self._SpeechServer__pitchInfo:
- return 5
- (minPitch, averagePitch, maxPitch) = self._SpeechServer__pitchInfo[speaker]
- pitch = speaker.getParameterValue('pitch')
- if pitch < averagePitch:
- return 5 * (pitch - minPitch) / (averagePitch - minPitch)
- if pitch > averagePitch:
- return 5 + 5 * (pitch - averagePitch) / (maxPitch - averagePitch)
- return 5
-
-
- def __setPitch(self, speaker, acssPitch):
- '''Determines the voice-specific pitch setting for the
- voice-independent ACSS pitch value.
- '''
- if speaker not in self._SpeechServer__pitchInfo:
- return None
- (minPitch, averagePitch, maxPitch) = self._SpeechServer__pitchInfo[speaker]
- if acssPitch < 5:
- pitch = minPitch + acssPitch * (averagePitch - minPitch) / 5
- elif acssPitch > 5:
- pitch = averagePitch + (acssPitch - 5) * (maxPitch - averagePitch) / 5
- else:
- pitch = averagePitch
- speaker.setParameterValue('pitch', pitch)
-
-
- def __setVolume(self, speaker, acssGain):
- '''Determines the voice-specific rate setting for the
- voice-independent ACSS rate value.
- '''
- if speaker not in self._SpeechServer__volumeInfo:
- return None
- (minVolume, averageVolume, maxVolume) = self._SpeechServer__volumeInfo[speaker]
- volume = minVolume + acssGain * (maxVolume - minVolume) / 10
- speaker.setParameterValue('volume', volume)
-
-
- def __getSpeaker(self, acss = None):
- voices = settings.voices
- defaultACSS = voices[settings.DEFAULT_VOICE]
- if not acss:
- acss = defaultACSS
-
- if acss.name() in self._SpeechServer__speakers:
- return self._SpeechServer__speakers[acss.name()]
- languages = []
-
- try:
- if ACSS.FAMILY in acss:
- family = acss[ACSS.FAMILY]
- languages = [
- family[speechserver.VoiceFamily.LOCALE]]
- elif ACSS.FAMILY in defaultACSS:
- family = defaultACSS[ACSS.FAMILY]
- languages = [
- family[speechserver.VoiceFamily.LOCALE]]
- except:
- acss.name() in self._SpeechServer__speakers
-
- if len(languages) == 0:
- import locale
- (language, encoding) = locale.getdefaultlocale()
- languages = [
- language]
-
- voices = self._SpeechServer__driver.getAllVoices()
- foundVoices = []
- for voice in voices:
- match = 0
- for language in languages:
- match = max(match, _matchLanguage(voice.language, language))
-
- if match == 2:
- foundVoices.insert(0, voice)
- continue
- if match:
- foundVoices.append(voice)
- continue
-
- if len(foundVoices):
- voices = foundVoices
- else:
- voices = self._SpeechServer__driver.getAllVoices()
- familyName = None
- if ACSS.FAMILY in acss:
- family = acss[ACSS.FAMILY]
- familyName = family[speechserver.VoiceFamily.NAME]
- elif ACSS.FAMILY in defaultACSS:
- family = defaultACSS[ACSS.FAMILY]
- familyName = family[speechserver.VoiceFamily.NAME]
-
- found = False
- for voice in voices:
- if not familyName or voice.name == familyName:
- found = True
- break
- continue
-
- if not found:
- if len(voices) == 0:
- return None
- voice = voices[0]
-
- s = self._SpeechServer__driver.createSpeaker(voice)
- speaker = _Speaker(s._narrow(GNOME.Speech.Speaker), voice)
-
- try:
- parameters = speaker.getSupportedParameters()
- for parameter in parameters:
- if parameter.name == 'punctuation mode':
- speaker.setParameterValue('punctuation mode', 0)
- break
- continue
- except:
- pass
-
- speaker.registerCallback(self)
- saveParameters = True
- for existingSpeaker in self._SpeechServer__speakers.values():
- if existingSpeaker.voiceInfo == speaker.voiceInfo:
-
- try:
- self._SpeechServer__rateInfo[speaker] = self._SpeechServer__rateInfo[existingSpeaker]
- except:
- pass
-
-
- try:
- self._SpeechServer__pitchInfo[speaker] = self._SpeechServer__pitchInfo[existingSpeaker]
- except:
- pass
-
-
- try:
- self._SpeechServer__volumeInfo[speaker] = self._SpeechServer__volumeInfo[existingSpeaker]
- except:
- pass
-
- saveParameters = False
- break
- continue
-
- if saveParameters:
- parameters = speaker.getSupportedParameters()
- for parameter in parameters:
- if parameter.name == 'rate':
- self._SpeechServer__rateInfo[speaker] = [
- parameter.min,
- parameter.current,
- parameter.max]
- continue
- if parameter.name == 'pitch':
- self._SpeechServer__pitchInfo[speaker] = [
- parameter.min,
- parameter.current,
- parameter.max]
- continue
- if parameter.name == 'volume':
- self._SpeechServer__volumeInfo[speaker] = [
- parameter.min,
- parameter.current,
- parameter.max]
- continue
-
-
- if ACSS.RATE in acss:
- self._SpeechServer__setRate(speaker, acss[ACSS.RATE])
-
- if ACSS.AVERAGE_PITCH in acss:
- self._SpeechServer__setPitch(speaker, acss[ACSS.AVERAGE_PITCH])
-
- if ACSS.GAIN in acss:
- self._SpeechServer__setVolume(speaker, acss[ACSS.GAIN])
-
- self._SpeechServer__speakers[acss.name()] = speaker
- return speaker
-
-
- def __idleHandler(self):
- '''Called by the gidle thread when there is something to do.
- The goal is to try to do all AT-SPI interactions on the gidle
- thread as a means to help prevent hangs.'''
- (thisId, thisType, offset) = self._SpeechServer__eventQueue.get()
- offset = self._SpeechServer__adjustTextCharIndex(offset)
- if self._SpeechServer__sayAll:
- if self._SpeechServer__sayAll.idForCurrentContext == thisId:
- context = self._SpeechServer__sayAll.currentContext
- if thisType == GNOME.Speech.speech_callback_speech_started:
- context.currentOffset = context.startOffset
- self._SpeechServer__sayAll.progressCallback(self._SpeechServer__sayAll.currentContext, speechserver.SayAllContext.PROGRESS)
- elif thisType == GNOME.Speech.speech_callback_speech_progress:
- context.currentOffset = context.startOffset + offset
- self._SpeechServer__sayAll.progressCallback(self._SpeechServer__sayAll.currentContext, speechserver.SayAllContext.PROGRESS)
- elif thisType == GNOME.Speech.speech_callback_speech_ended:
-
- try:
- while True:
- (self._SpeechServer__sayAll.currentContext, acss) = self._SpeechServer__sayAll.utteranceIterator.next()
- utterance = self._SpeechServer__sayAll.currentContext.utterance
- logLine = "SPEECH OUTPUT: '" + utterance + "'"
- debug.println(debug.LEVEL_INFO, logLine)
- log.info(logLine)
- if utterance and len(utterance) and not utterance.isspace():
- self._SpeechServer__sayAll.idForCurrentContext = self._SpeechServer__speak(utterance, acss)
- break
- continue
- except StopIteration:
- self._SpeechServer__isSpeaking = False
- context.currentOffset = context.endOffset
- self._SpeechServer__sayAll.progressCallback(self._SpeechServer__sayAll.currentContext, speechserver.SayAllContext.COMPLETED)
- self._SpeechServer__sayAll = None
- except:
- None<EXCEPTION MATCH>StopIteration
-
-
- None<EXCEPTION MATCH>StopIteration
-
-
- rerun = True
- self._SpeechServer__gidleLock.acquire()
- if self._SpeechServer__eventQueue.empty():
- self._SpeechServer__gidleId = 0
- rerun = False
-
- self._SpeechServer__gidleLock.release()
- return rerun
-
-
- def notify(self, progressType, utteranceId, offset):
- '''Called by GNOME Speech when the GNOME Speech driver generates
- a callback. This is for internal use only.
-
- Arguments:
- - progressType: one of GNOME.Speech.speech_callback_speech_started,
- GNOME.Speech.speech_callback_speech_progress,
- GNOME.Speech.speech_callback_speech_ended
- - utteranceId: the id of the utterance (returned by say)
- - offset: the character offset into the utterance (for progress)
- '''
- if progressType == GNOME.Speech.speech_callback_speech_started:
- self._SpeechServer__isSpeaking = True
- elif progressType == GNOME.Speech.speech_callback_speech_progress:
- self._SpeechServer__isSpeaking = True
- elif progressType == GNOME.Speech.speech_callback_speech_ended and not (self._SpeechServer__sayAll):
- self._SpeechServer__isSpeaking = False
-
- if self._SpeechServer__sayAll:
- self._SpeechServer__gidleLock.acquire()
- self._SpeechServer__eventQueue.put((utteranceId, progressType, offset))
- if not self._SpeechServer__gidleId:
- if settings.gilSleepTime:
- time.sleep(settings.gilSleepTime)
-
- self._SpeechServer__gidleId = gobject.idle_add(self._SpeechServer__idleHandler)
-
- self._SpeechServer__gidleLock.release()
-
-
-
- def getInfo(self):
- '''Returns [driverName, serverId]
- '''
- return [
- self._SpeechServer__driverName,
- self._SpeechServer__iid]
-
-
- def getVoiceFamilies(self):
- '''Returns a list of speechserver.VoiceFamily instances
- representing all the voice families known by the speech server.
- '''
- families = []
-
- try:
- for voice in self._SpeechServer__driver.getAllVoices():
- props = {
- speechserver.VoiceFamily.NAME: voice.name,
- speechserver.VoiceFamily.LOCALE: voice.language }
- families.append(speechserver.VoiceFamily(props))
- except:
- debug.printException(debug.LEVEL_SEVERE)
-
- return families
-
-
- def queueText(self, text = '', acss = None):
- '''Adds the text to the queue.
-
- Arguments:
- - text: text to be spoken
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
-
- Output is produced by the next call to speak.
- '''
- self.speak(text, acss)
-
-
- def queueTone(self, pitch = 440, duration = 50):
- '''Adds a tone to the queue.
-
- Output is produced by the next call to speak.
- '''
- pass
-
-
- def queueSilence(self, duration = 50):
- '''Adds silence to the queue.
-
- Output is produced by the next call to speak.
- '''
- pass
-
-
- def speakCharacter(self, character, acss = None):
- '''Speaks a single character immediately.
-
- Arguments:
- - character: text to be spoken
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- '''
- chname = chnames.getCharacterName(character)
- if orca_state.activeScript and orca_state.usePronunciationDictionary:
- chname = orca_state.activeScript.adjustForPronunciation(chname)
-
- self.speak(chname, acss)
-
-
- def speakUtterances(self, utterances, acss = None, interrupt = True):
- '''Speaks the given list of utterances immediately.
-
- Arguments:
- - utterances: list of strings to be spoken
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- - interrupt: if True, stop any speech currently in progress.
- '''
- i = 0
- for text in utterances:
- if len(text):
- if interrupt:
- pass
- self.speak(text, acss, i == 0)
-
- i += 1
-
-
-
- def __adjustTextCharIndex(self, offset):
- '''Get the original character index into the text string (before
- the string was adjusted for verbalized punctuation.
-
- Arguments:
- - offset: character offset into text string
-
- Returns the equivalent character index into the original text string.
- '''
- equivalentIndex = 0
- for i in range(0, len(self.textCharIndices)):
- equivalentIndex = i
- if self.textCharIndices[i] >= offset:
- break
- continue
-
- return equivalentIndex
-
-
- def __addVerbalizedPunctuation(self, oldText):
- '''Depending upon the users verbalized punctuation setting,
- adjust punctuation symbols in the given text to their pronounced
- equivalents. The pronounced text will either replace the
- punctuation symbol or be inserted before it. In the latter case,
- this is to retain spoken prosity.
-
- If we are moving around by single characters, then always speak
- the punctuation. We try to detect this by looking for just a
- single character being spoken.
-
- Arguments:
- - oldText: text to be parsed for punctuation.
-
- Returns a text string with the punctuation symbols adjusted accordingly.
- '''
- oldText = oldText.replace('...', _(' dot dot dot'), 1)
- oldText = oldText.replace('\xe2\x80\xa6', _(' dot dot dot'), 1)
- oldText = oldText.decode('UTF-8')
- removeNewLines = True
- if orca_state.lastInputEvent and 'event_string' in orca_state.lastInputEvent.__dict__:
- lastKey = orca_state.lastInputEvent.event_string
- if lastKey == 'Left' or lastKey == 'Right':
- removeNewLines = False
-
-
- if removeNewLines:
- oldText = oldText.replace('\n', '', 1)
-
- self.textCharIndices = []
- style = settings.verbalizePunctuationStyle
- newText = ''
- for i in range(0, len(oldText)):
- self.textCharIndices.append(len(newText))
-
- try:
- (level, action) = punctuation_settings.getPunctuationInfo(oldText[i])
- isPrev = isNext = isSpecial = False
- if i > 0:
- isPrev = not oldText[i - 1].isspace()
-
- if i < len(oldText) - 1:
- isNext = not oldText[i + 1].isspace()
-
- if isPrev and isNext:
- pass
- isSpecial = oldText[i] == '.'
- prevCharMatches = nextCharMatches = False
- if orca_state.activeScript:
- currencySymbols = orca_state.activeScript.getUnicodeCurrencySymbols()
-
- if i == 0:
- prevCharMatches = True
-
- if i > 0:
- prevCharMatches = oldText[i - 1].isspace()
-
- if i < len(oldText) - 1:
- if not oldText[i + 1].isdigit():
- pass
- nextCharMatches = oldText[i + 1] in currencySymbols
-
- if oldText[i] == '-' and style != settings.PUNCTUATION_STYLE_NONE and prevCharMatches and nextCharMatches:
- if isPrev:
- newText += ' '
-
- newText += _('minus')
- elif len(oldText) == 1 and isSpecial or style <= level:
- if isPrev:
- newText += ' '
-
- newText += chnames.getCharacterName(oldText[i])
- if action == punctuation_settings.PUNCTUATION_INSERT and not isNext:
- newText += oldText[i].encode('UTF-8')
-
- if isNext:
- newText += ' '
-
- else:
- newText += oldText[i].encode('UTF-8')
- continue
- if len(oldText) == 1:
- newText += chnames.getCharacterName(oldText[i])
- else:
- newText += oldText[i].encode('UTF-8')
-
-
- return newText
-
-
- def __speak(self, text = None, acss = None, interrupt = True):
- '''Speaks all queued text immediately. If text is not None,
- it is added to the queue before speaking.
-
- Arguments:
- - text: optional text to add to the queue before speaking
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- - interrupt: if True, stops any speech in progress before
- speaking the text
-
- Returns an id of the thing being spoken or -1 if nothing is to
- be spoken.
- '''
- if not settings.enableSpeech:
- return -1
- speaker = self._SpeechServer__getSpeaker(acss)
- if acss and ACSS.RATE not in acss:
- voices = settings.voices
- defaultACSS = voices[settings.DEFAULT_VOICE]
- if ACSS.RATE in defaultACSS:
- self._SpeechServer__setRate(speaker, defaultACSS[ACSS.RATE])
-
-
- if not text:
- if interrupt:
- speech.stop()
-
- return -1
- text = self._SpeechServer__addVerbalizedPunctuation(text)
-
- try:
- self._SpeechServer__lastText = [
- text,
- acss]
- self._SpeechServer__isSpeaking = True
- return speaker.say(text)
- except:
- text
- debug.printException(debug.LEVEL_SEVERE)
- debug.println(debug.LEVEL_SEVERE, 'Restarting speech...')
- self.reset()
- return -1
-
-
-
- def speak(self, text = None, acss = None, interrupt = True):
- '''Speaks all queued text immediately. If text is not None,
- it is added to the queue before speaking.
-
- Arguments:
- - text: optional text to add to the queue before speaking
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- - interrupt: if True, stops any speech in progress before
- speaking the text
- '''
- if self._SpeechServer__sayAll:
- self.stop()
-
- if not acss and text and text.isupper():
-
- try:
- acss = orca_state.activeScript.voices[settings.UPPERCASE_VOICE]
-
-
- self._SpeechServer__speak(text, acss, interrupt)
-
-
- def isSpeaking(self):
- '''"Returns True if the system is currently speaking.'''
- return self._SpeechServer__isSpeaking
-
-
- def sayAll(self, utteranceIterator, progressCallback):
- '''Iterates through the given utteranceIterator, speaking
- each utterance one at a time.
-
- Arguments:
- - utteranceIterator: iterator/generator whose next() function
- returns a new string to be spoken
- - progressCallback: called as progress is made
- '''
-
- try:
- (context, acss) = utteranceIterator.next()
- logLine = "SPEECH OUTPUT: '" + context.utterance + "'"
- debug.println(debug.LEVEL_INFO, logLine)
- log.info(logLine)
- self._SpeechServer__sayAll = _SayAll(utteranceIterator, context, self._SpeechServer__speak(context.utterance, acss), progressCallback)
- except StopIteration:
- pass
-
-
-
- def increaseSpeechPitch(self, step = 0.5):
- '''Increases the speech pitch for the default voice.
-
- Arguments:
- - step: the pitch step increment.
- '''
- voices = settings.voices
- acss = voices[settings.DEFAULT_VOICE]
- speaker = self._SpeechServer__getSpeaker(acss)
- pitchDelta = settings.speechPitchDelta
-
- try:
- pitch = min(10, self._SpeechServer__getPitch(speaker) + pitchDelta)
- acss[ACSS.AVERAGE_PITCH] = pitch
- self._SpeechServer__setPitch(speaker, pitch)
- debug.println(debug.LEVEL_CONFIGURATION, 'speech.increaseSpeechPitch: pitch is now %d' % pitch)
- self.speak(_('higher.'))
- except:
- debug.printException(debug.LEVEL_SEVERE)
-
-
-
- def decreaseSpeechPitch(self, step = 0.5):
- '''Decreases the speech pitch for the default voice.
-
- Arguments:
- - step: the pitch step decrement.
- '''
- voices = settings.voices
- acss = voices[settings.DEFAULT_VOICE]
- speaker = self._SpeechServer__getSpeaker(acss)
- pitchDelta = settings.speechPitchDelta
-
- try:
- pitch = max(1, self._SpeechServer__getPitch(speaker) - pitchDelta)
- acss[ACSS.AVERAGE_PITCH] = pitch
- self._SpeechServer__setPitch(speaker, pitch)
- debug.println(debug.LEVEL_CONFIGURATION, 'speech.decreaseSpeechPitch: pitch is now %d' % pitch)
- self.speak(_('lower.'))
- except:
- debug.printException(debug.LEVEL_SEVERE)
-
-
-
- def increaseSpeechRate(self, step = 5):
- '''Increases the speech rate.
-
- [[[TODO: WDW - this is a hack for now. Need to take min/max
- values in account, plus also need to take into account that
- different engines provide different rate ranges.]]]
- '''
- voices = settings.voices
- acss = voices[settings.DEFAULT_VOICE]
- speaker = self._SpeechServer__getSpeaker(acss)
- rateDelta = settings.speechRateDelta
-
- try:
- rate = min(100, self._SpeechServer__getRate(speaker) + rateDelta)
- acss[ACSS.RATE] = rate
- self._SpeechServer__setRate(speaker, rate)
- debug.println(debug.LEVEL_CONFIGURATION, 'speech.increaseSpeechRate: rate is now %d' % rate)
- self.speak(_('faster.'))
- except:
- debug.printException(debug.LEVEL_SEVERE)
-
-
-
- def decreaseSpeechRate(self, step = 5):
- '''Decreases the rate of speech for the given ACSS. If
- acssName is None, the rate decrease will be applied to all
- known ACSSs.
-
- [[[TODO: WDW - this is a hack for now. Need to take min/max
- values in account, plus also need to take into account that
- different engines provide different rate ranges.]]]
-
- Arguments:
- -acssName: the ACSS whose speech rate should be decreased
- '''
- voices = settings.voices
- acss = voices[settings.DEFAULT_VOICE]
- speaker = self._SpeechServer__getSpeaker(acss)
- rateDelta = settings.speechRateDelta
-
- try:
- rate = max(1, self._SpeechServer__getRate(speaker) - rateDelta)
- acss[ACSS.RATE] = rate
- self._SpeechServer__setRate(speaker, rate)
- debug.println(debug.LEVEL_CONFIGURATION, 'speech.decreaseSpeechRate: rate is now %d' % rate)
- self.speak(_('slower.'))
- except:
- debug.printException(debug.LEVEL_SEVERE)
-
-
-
- def stop(self):
- '''Stops ongoing speech and flushes the queue.'''
- if self._SpeechServer__sayAll:
- self._SpeechServer__sayAll.progressCallback(self._SpeechServer__sayAll.currentContext, speechserver.SayAllContext.INTERRUPTED)
- self._SpeechServer__sayAll = None
-
- for name in self._SpeechServer__speakers.keys():
-
- try:
- self._SpeechServer__speakers[name].stop()
- continue
- continue
-
-
- self._SpeechServer__isSpeaking = False
-
-
- def shutdown(self):
- '''Shuts down the speech engine.'''
- if self._SpeechServer__iid in SpeechServer._SpeechServer__activeServers:
- for speaker in self._SpeechServer__speakers.values():
- speaker.stop()
- speaker.unref()
-
- self._SpeechServer__speakers = { }
-
- try:
- self._SpeechServer__driver.unref()
- except:
- pass
-
- self._SpeechServer__driver = None
- del SpeechServer._SpeechServer__activeServers[self._SpeechServer__iid]
-
-
-
- def reset(self, text = None, acss = None):
- '''Resets the speech engine.'''
- if time.time() - self._SpeechServer__lastResetTime < 20:
- debug.println(debug.LEVEL_SEVERE, 'Something looks wrong with speech. Aborting.')
- debug.printStack(debug.LEVEL_ALL)
- orca.die(50)
- else:
- self._SpeechServer__lastResetTime = time.time()
- speakers = self._SpeechServer__speakers
- self.shutdown()
- servers = bonobo.activation.query("repo_ids.has('IDL:GNOME/Speech/SynthesisDriver:0.3')")
- for server in servers:
- if server.iid == self._SpeechServer__iid:
-
- try:
- self._SpeechServer__driver = self._SpeechServer__activateDriver(self._SpeechServer__iid)
- self._SpeechServer__speakers = { }
- for name in speakers.keys():
- self._SpeechServer__getSpeaker(speakers[name])
-
- if text:
- self.speak(text, acss)
-
- debug.printException(debug.LEVEL_SEVERE)
- self._SpeechServer__driver = None
-
- continue
-
-
-
-